home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol03 / 06 / sqlpop / sqlpop.c
C/C++ Source or Header  |  1988-11-10  |  10KB  |  444 lines

  1. /**********************************************************
  2.  * SQLPOP - allows the user to hot-key into an SQL
  3.  * Server query window
  4.  *
  5.  * Created by Marc Adler
  6.  **********************************************************/
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <memory.h>
  11. #include <string.h>
  12. #include <sqlfront.h>
  13. #include <sqldb.h>
  14. #include <netcons.h>
  15. #include <server.h>
  16. #include <os2def.h>
  17. #include <doscalls.h>
  18. #include <subcalls.h>
  19. #include <infoseg.h>
  20.  
  21. typedef unsigned char BOOL;
  22. typedef unsigned char BYTE;
  23. typedef unsigned int  WORD;
  24. typedef unsigned long DWORD;
  25.  
  26.  
  27. /* Structure of the keyboard packet which the device monitor receives */
  28.  
  29. typedef struct kbdpacket
  30. {
  31. WORD        monitor_flags;
  32. BYTE        ascii_code;
  33. BYTE        scan_code;
  34. WORD        nls;
  35. WORD        shift_code;
  36. DWORD    time;
  37. WORD        devdrv_flags;
  38. } KBDPACKET;
  39.  
  40. #define KEY_RELEASE        0x40
  41. #define ALT            0x08
  42.  
  43. #define IDNO            FALSE
  44. #define IDYES            TRUE
  45. #define MB_YESNO        1
  46.  
  47. #define ERR_DBSQLEXEC_FAILED    -100
  48. #define ERR_DBRESULTS_FAILED    -101
  49.  
  50. DBPROCESS *DBProc = NULL;    /* Our connection with the DataServer */
  51.  
  52. WORD        hMonitor;            /* Monitor handle */
  53. BOOL        bIsResident = FALSE;    /* TRUE once we become resident */
  54.  
  55. struct server_info_1 ServerInfo[65]; /* server_info_1 buffer area */
  56.  
  57. /***********************************************************
  58.  * Main()
  59.  *
  60.  * Logs into SQL Server, installs the monitor, and calls
  61.  * DoSQLPopup() when the user presses the ALT-S key.
  62.  **********************************************************/
  63.  
  64. main()
  65. {
  66.     KBDPACKET    packet;
  67.     int        packet_len;
  68.     char        inbuf[128], outbuf[128];
  69.   
  70.     /* Try to login */
  71.     if (!InitDB())
  72.         exit(1);
  73.  
  74.     bIsResident = TRUE;
  75.  
  76.     /* Open a keyboard monitor and register it */
  77.  
  78.     DOSMONOPEN((char far *) "KBD$", (unsigned far *) &hMonitor);
  79.     inbuf[0] = sizeof(inbuf);    inbuf[1] = 0;
  80.     outbuf[0] = sizeof(outbuf);  outbuf[1] = 0;
  81.     DOSMONREG(hMonitor, (char far *) inbuf, (char far *)
  82.             outbuf, 0, GetCurrScreenGroup());
  83.  
  84.     /* Monitor loop - watches for the ALT+S keystroke */
  85.     for (;;)
  86.     {
  87.         packet_len = sizeof(packet);
  88.         DOSMONREAD((char far *) inbuf, 0, (char far *) &
  89.                  packet, (unsigned far *) &packet_len);
  90.     
  91.     if (!(packet.devdrv_flags & KEY_RELEASE))
  92.     {
  93.         /* Check for an ALT-S keystroke. */
  94.  
  95.         if ((packet.shift_code & ALT) && 
  96.             packet.ascii_code == 0 && packet.scan_code == 31)
  97.         {
  98.             DoSQLPopup();
  99.             continue;
  100.         }
  101.     }
  102.  
  103.     /* Pass all other keys through */
  104.     DOSMONWRITE((char far *) outbuf, (char far *) &packet, packet_len);
  105.     }
  106. }
  107.  
  108.  
  109. /**********************************************************
  110.  * TerminateMonitor()
  111.  * Logs off the server and terminates the monitor.
  112.  *********************************************************/
  113.  
  114. TerminateMonitor()
  115. {
  116.     Logout();
  117.     DOSMONCLOSE(hMonitor);
  118.     DOSEXIT(1, 0);
  119. }
  120.  
  121.  
  122. /***********************************************************
  123.  * DoSQLPopup()
  124.  * Puts up a rudimentary one-line query box, gets the user's
  125.  * query, sends it to SQL Server, and prints the results.
  126.  * This is done when the user presses the proper hot-key
  127.  * sequence.
  128.  **********************************************************/
  129.  
  130. char *BoxStr[] =
  131. {
  132. "IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM;",
  133. ":                                                                              :",
  134. "HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM<"
  135. };
  136.  
  137. DoSQLPopup()
  138. {
  139.     unsigned    i;
  140.     int        row;
  141.     char        buf[82];
  142.     struct    KbdStringInLength ksl;
  143.     unsigned    waitflag;
  144.     unsigned    attr = 0x07;
  145.     int        nc, col, len;
  146.     char        *more = "Press a key for more...";
  147.  
  148.     /* Take over the screen group for a while */
  149.     waitflag = 0;
  150.     if (VIOPOPUP((unsigned far *) &waitflag, 0))
  151.             return;
  152.  
  153.     /* Draw the query box */
  154.     for (i = 0;  i <= 2;  i++)
  155.     {
  156.         VIOWRTCHARSTRATT((char far *) BoxStr[i],
  157.                     strlen(BoxStr[i]), i, 0, 
  158.                     (char far *) &attr, 0);
  159.     }
  160.  
  161.     VIOSETCURPOS(1, 1, 0);
  162.  
  163.     /* Get the user input. Get rid of trailing carruage returns. */
  164.     ksl.Length = sizeof(buf);
  165.     KBDSTRINGIN((char far *) buf, (struct KbdStringInLength
  166.                 far *) &ksl, 0, 0);
  167.     if (ksl.LengthB)
  168.     {
  169.         if (buf[ksl.LengthB] == '\r')
  170.               buf[ksl.LengthB] = '\0';
  171.     }
  172.  
  173.     /* If the user wants to exit the program, logout and
  174.      deinstall the monitor */
  175.  
  176.     if (!strcmpi(buf, "quit") || !strcmpi(buf, "exit"))
  177.     {
  178.         VIOENDPOPUP(0);
  179.         TerminateMonitor();
  180.     }
  181.  
  182.     /* Ship the query to SQL Server */
  183.  
  184.     dbcmd(DBProc, buf);
  185.     if (dbsqlexec(DBProc) != FAIL) 
  186.     {
  187.         while (dbresults(DBProc) != NO_MORE_RESULTS)
  188.         {
  189.             char results_buf[256], *rb;
  190.  
  191.             /* Find out how many columns each row has */
  192.             nc = dbnumcols(DBProc);
  193.             /* Insert the row data one column at a time
  194.              * into the buffer */
  195.             for (rb = results_buf, col = 1;  col <= nc;  col++)
  196.             {
  197.                 dbbind(DBProc, col, CHARBIND, 0, rb);
  198.                 len = dbcollen(DBProc, col);
  199.                 rb += len;
  200.             }
  201.             *rb = '\0';
  202.  
  203.             /* Print out the results */
  204.             for (row = 3;  dbnextrow(DBProc) !=
  205.                 NO_MORE_ROWS;  row++)
  206.             {
  207.                 VIOWRTCHARSTRATT((char far *)
  208.                     results_buf, strlen(results_buf),
  209.                     row, 0, (char far *) &attr, 0);
  210.                 if (row > 22)
  211.                 {
  212.                     VIOWRTCHARSTRATT((char far *) more,
  213.                         strlen(more), row, 0, 
  214.                         (char far *) &attr, 0);
  215.                     getch();
  216.                     row = 3;
  217.                 }
  218.             }
  219.         }
  220.     }
  221.  
  222.     VIOWRTCHARSTRATT((char far *) more, strlen(more), 24,
  223.                     0, (char far *) &attr, 0);
  224.     getch();
  225.  
  226.     VIOENDPOPUP(0);
  227. }
  228.  
  229.  
  230. /**********************************************************
  231.  * InitDB()
  232.  * Installs the error handler and tries to login to SQL
  233.  * Server.
  234.  **********************************************************/
  235.  
  236. InitDB()
  237. {
  238.     int DBErrorHandler();
  239.  
  240.     /* Install our error handler */
  241.     dberrhandle(DBErrorHandler);
  242.  
  243.     /* Try to login to SQL Server */
  244.     if (!DoLogin())
  245.         return FALSE;
  246.     return TRUE;
  247. }
  248.  
  249.  
  250. /**********************************************************
  251.  * DoLogin()
  252.  * Executed at startup and when user chooses LOGIN
  253.  * from the menu.
  254.  *
  255.  * RETURNS
  256.  *
  257.  * TRUE if the login is successful, FALSE if not.
  258.  **********************************************************/
  259.  
  260. DoLogin()
  261. {
  262.     LOGINREC    *login;    /* Our login information */
  263.     int        iServer;
  264.  
  265.     /* Find all servers we are connected to who are running SQL SERVER */
  266.     if ((iServer = LocateSQLServer()) == FALSE)
  267.         return FALSE;
  268.  
  269.     /* Get a login structure and set the app name, the
  270.        login id, and the pwd. */
  271.     login = dblogin();
  272.     DBSETLAPP(login, "Adler");
  273.     DBSETLUSER(login, "sa");
  274.     DBSETLPWD(login, "");
  275.  
  276.     /* Open a new DBProc structure with the new login info.
  277.        If we fail, then DB_LIB will print out an message
  278.        through the error handler. */
  279.  
  280.     if ((DBProc = dbopen(login,
  281.         ServerInfo[iServer].sv1_name)) == NULL)
  282.         return FALSE;
  283.     return TRUE;    /* Successful login ! */
  284. }
  285.  
  286. /**********************************************************
  287.  * Logout()
  288.  * Closes the DBProc upon exit.  We call this when we end
  289.  * our keyboard monitor.
  290.  **********************************************************/
  291.  
  292. Logout()
  293. {
  294.     if(DBProc)
  295.     { 
  296.         dbclose(DBProc);
  297.         DBProc = NULL;
  298.     }
  299. }
  300.  
  301.  
  302. /**********************************************************
  303.  * DBErrorHandler()
  304.  * Handles error conditions from SQL Server. Puts up a
  305.  * message box and asks the user for an action.
  306.  **********************************************************/
  307.  
  308. int DBErrorHandler(dbproc, severity, errno, oserr)
  309. DBPROCESS    *dbproc;
  310. int        severity,
  311.         errno,
  312.         oserr;
  313. {
  314. /* Print the SQL Server error message */
  315.  
  316. if (MessageBox("SQL Server Error!!!", 
  317.         dberrstr(errno),
  318.         "Continue the program?",
  319.         MB_YESNO) == IDNO)
  320. {
  321.     TerminateMonitor();
  322.     return INT_EXIT;
  323. }
  324.  
  325. /* See if we have an operating system error */
  326. if (oserr != DBNOERR)
  327.     if (MessageBox("OS/2 Error!!!",
  328.             dboserrstr(oserr),
  329.             "Continue the program?",
  330.             MB_YESNO) == IDNO)
  331.     {
  332.         TerminateMonitor();
  333.         return INT_EXIT;
  334.     }
  335.  
  336. /* If for some reason the DBProc structure is dead,
  337.  * exit immediately */
  338.  
  339. if (DBDEAD(dbproc))
  340. {
  341.     TerminateMonitor();
  342.     return INT_EXIT;
  343. }
  344.  
  345. /* Tell DB-LIB to cancel the command and continue. */
  346.  
  347. return INT_CANCEL;
  348. }
  349.  
  350.  
  351. /**********************************************************
  352.  * printmsgs()
  353.  * Fetches any pending messages from SQL Server and 
  354.  * inserts them into the results buffer.
  355.  *
  356.  * RETURNS - nothing
  357.  **********************************************************/
  358.  
  359. void printmsgs(dbproc)
  360. DBPROCESS *dbproc;
  361.  
  362. {
  363.     char *msg;
  364.  
  365.     while ((msg = dbgetmsg(dbproc)) != NULL)
  366.         fprintf(stderr, "%s\n", msg);
  367. }
  368.  
  369.  
  370. MessageBox(s1, s2, s3, action)
  371. char *s1, *s2, *s3;
  372. unsigned  action;
  373.  
  374. {
  375.     int    c;
  376.  
  377.     if(s1)
  378.     {
  379.         fprintf(stderr, "%s", s1);
  380.         if(s2)
  381.         {
  382.             fprintf(stderr, "\n%s", s2);
  383.             if(s3)
  384.             {
  385.                 fprintf(stderr, "\n%s", s3);
  386.             }
  387.         }
  388.     }
  389.   
  390.     switch(action)
  391.     {
  392.         case MB_YESNO :
  393.             if ((c = getch()) == 'Y' || c == 'y')
  394.                 return IDYES;
  395.             return IDNO;
  396.     }
  397. }
  398.  
  399.  
  400. /**********************************************************
  401.  * GetCurrScreenGroup()
  402.  *
  403.  * Returns the id of the current screen group.
  404.  **********************************************************/
  405.  
  406. #define    MAKEPGINFOSEG(sel)    (MAKEP(sel, 0))
  407.  
  408. GetCurrScreenGroup()
  409. {
  410.     unsigned ldt_seg, gdt_seg;
  411.     struct InfoSegGDT far *pGdt;
  412.  
  413.     DOSGETINFOSEG((unsigned far *) &gdt_seg, 
  414.                 (unsigned far *) &ldt_seg);
  415.     pGdt = MAKEPGINFOSEG(gdt_seg);    /* Get a pointer to the info */
  416.     return pGdt->CurScrnGrp;        /* return the screen group   */
  417. }
  418.  
  419.  
  420. LocateSQLServer()
  421. {
  422.     unsigned entriesread;    /* number of entries read by
  423.                            NetServerEnum */
  424.     unsigned totalentries;    /* total number of entries
  425.                            available */
  426.     int i, rc;
  427.  
  428.     rc = NetServerEnum((char far *) NULL, 1,
  429.                 (char far *) ServerInfo,
  430.                 sizeof(ServerInfo),
  431.                 (unsigned far *) &entriesread,
  432.                 (unsigned far *) &totalentries);
  433.     if (!rc)
  434.     {
  435.         for (i = 0;  i < entriesread;  i++)
  436.         if (ServerInfo[i].sv1_type & SV_TYPE_SQLSERVER)
  437.             return i + 1;    /* use offset of 1 so we
  438.                            don't return a '0' */
  439.     }
  440.   
  441.     fprintf(stderr, "Could not find an SQL Server\n");
  442.     return FALSE;
  443. }
  444.